#include"requestor.hpp"
namespace bitRPC{
    namespace client{
        class RpcCaller
        {
            public:
                using ptr=std::shared_ptr<RpcCaller>;
                using JsonResponseCallback=std::function<void(const Json::Value&)>;
                using JsonAsyncResponse=std::future<Json::Value>;
                RpcCaller(const Requestor::ptr& requestor):_requestor(requestor){}
                //同步
                bool call(const BaseConnection::ptr &conn,const std::string& method,
                    const Json::Value& params,Json::Value& result)
                {
                    //组织请求
                    auto rpc_msg=MessageFactory::create<RpcRequest>();
                    rpc_msg->setParam(params);
                    rpc_msg->setId(UUID::uuid());
                    rpc_msg->setMethod(method);
                    rpc_msg->setMType(MType::REQ_RPC);
                    BaseMessage::ptr rsp_msg;
                    // 发送请求
                    bool ret=_requestor->send(conn,std::dynamic_pointer_cast<BaseMessage>(rpc_msg),rsp_msg);
                    // 等待响应
                    if(ret==false)
                    {
                        ELOG("同步RPC请求失败！");
                        return false;
                    }
                    auto rpc_rsp_msg=std::dynamic_pointer_cast<RpcResponse>(rsp_msg);
                    if(!rpc_rsp_msg)
                    {
                         ELOG("rpc_rsp_msg向下转换失败！");
                         return false;
                    }
                    if(rpc_rsp_msg->rcode()!=Rcode::RCODE_OK)
                    {
                        ELOG("RPC请求出错！%s",errReason(rpc_rsp_msg->rcode()));
                        return false;
                    }
                    result=rpc_rsp_msg->result();
                    return true;
                }
                //异步
                bool call(const BaseConnection::ptr &conn,const std::string& method,
                    const Json::Value& params,std::future<Json::Value>& result)
                {
                    //组织请求
                    auto rpc_msg=MessageFactory::create<RpcRequest>();
                    rpc_msg->setParam(params);
                    rpc_msg->setId(UUID::uuid());
                    rpc_msg->setMethod(method);
                    rpc_msg->setMType(MType::REQ_RPC);
                    BaseMessage::ptr rsp_msg;
                    auto json_promise=std::shared_ptr<std::promise<Json::Value>>();
                    result=json_promise->get_future();
                    Requestor::RequestCallback cb =std::bind(RpcCaller::Callback,this,json_promise,std::placeholders::_1);
                    // 发送请求
                    bool ret=_requestor->send(conn,std::dynamic_pointer_cast<BaseMessage>(rpc_msg),cb);
                    // 等待响应
                    if(ret==false)
                    {
                        ELOG("同步RPC请求失败！");
                        return false;
                    }
                    return true;

                }
                // 回调
                bool call(const BaseConnection::ptr &conn,const std::string& method,
                    const Json::Value& params,const JsonResponseCallback& cb)
                {
                    //组织请求
                    auto rpc_msg=MessageFactory::create<RpcRequest>();
                    rpc_msg->setParam(params);
                    rpc_msg->setId(UUID::uuid());
                    rpc_msg->setMethod(method);
                    rpc_msg->setMType(MType::REQ_RPC);
                    Requestor::RequestCallback rpc_cb =std::bind(RpcCaller::Callback1,this,cb,std::placeholders::_1);
                    // 发送请求
                    bool ret=_requestor->send(conn,std::dynamic_pointer_cast<BaseMessage>(rpc_msg),rpc_cb);
                    // 等待响应
                    if(ret==false)
                    {
                        ELOG("同步RPC请求失败！");
                        return false;
                    }
                    return true;
                }
            private:
                void Callback1(JsonResponseCallback &result ,BaseMessage::ptr rsp_msg)
                {
                    auto rpc_rsp_msg=std::dynamic_pointer_cast<RpcResponse>(rsp_msg);
                    if(!rpc_rsp_msg)
                    {
                         ELOG("rpc_rsp_msg向下转换失败！");
                         return ;
                    }
                    if(rpc_rsp_msg->rcode()!=Rcode::RCODE_OK)
                    {
                        ELOG("RPC请求出错！%s",errReason(rpc_rsp_msg->rcode()));
                        return ;
                    }
                    result(rpc_rsp_msg->result());
                }
                void Callback(std::shared_ptr<std::promise<Json::Value>> result,BaseMessage::ptr rsp_msg)
                {
                    auto rpc_rsp_msg=std::dynamic_pointer_cast<RpcResponse>(rsp_msg);
                    if(!rpc_rsp_msg)
                    {
                         ELOG("rpc_rsp_msg向下转换失败！");
                         return ;
                    }
                    if(rpc_rsp_msg->rcode()!=Rcode::RCODE_OK)
                    {
                        ELOG("RPC请求出错！%s",errReason(rpc_rsp_msg->rcode()));
                        return ;
                    }
                    result->set_value(rpc_rsp_msg->result());
                }
            private:
                Requestor::ptr _requestor;
        };
    }
}